/****************************************
*
*	EoSC_Camera
*	
*	Controls the location, rotation and behaviour of the camera.
*	See EoSC_CameraProperties <Header> for more information on how to handle the camera.
*
*	ToDo:
*	Needs tweaking...
*	I REALLY NEED TO LEARN HOW ARCHETYPES WORK :D
*
****************************************/

class EoSC_Camera extends Camera;

// Reference to the camera properties.
var const EoSC_CameraProperties CameraProperties;


// Change the basic behaviour of the ViewTarget function.
function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{
	local Pawn Pawn;
	local Vector V, PotentialCameraLocation, HitLocation, HitNormal;
	local Actor HitActor;

	if (CameraProperties == None)
	{
		Super.UpdateViewTarget(OutVT, DeltaTime);
	}

	// If we have an interpolation do not update!
	if (PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing)
	{
		return;
	}

	Pawn = Pawn(OutVT.Target);
	if (Pawn != None)
	{
		// Check if we have a valid Socket to attach the camera.
		if (Pawn.Mesh != None && Pawn.Mesh.GetSocketByName(CameraProperties.PawnSocketName) != None)
		{
			Pawn.Mesh.GetSocketWorldLocationAndRotation(CameraProperties.PawnSocketName, OutVT.POV.Location, OutVT.POV.Rotation);
		}
		// If not use the eye view for it.
		else
		{
			OutVT.Target.GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
		}

		// If we use the target rotation, we need to catch it. I recommend to use it always otherwise the cam will make you puke.
		if (CameraProperties.UseTargetRotation)
		{
			OutVT.Target.GetActorEyesViewPoint(V, OutVT.POV.Rotation);
		}

		// Add the camera offset.
		OutVT.POV.Rotation += CameraProperties.CameraRotationOffset;
		// Get the camera location.
		PotentialCameraLocation = OutVT.POV.Location + (CameraProperties.CameraOffset >> OutVT.POV.Rotation);		

		// Trace out to see if the potential camera location will be acceptable or not.
		HitActor = Trace(HitLocation, HitNormal, PotentialCameraLocation, OutVT.POV.Location, true,,, TRACEFLAG_BULLET);
		// We need a hit detection to see if we collide with meshes or csg.
		if (HitActor != None && HitActor.bWorldGeometry)
		{
			OutVT.POV.Location = HitLocation + HitNormal * 16.f;
		}
		else
		{
			OutVT.POV.Location = PotentialCameraLocation;
		}
	}
}

defaultproperties
{
	// The reference to our settings archetype inside the editor.
	CameraProperties=EoSC_CameraProperties'Archetypes.Cameras.AT_DefaultCamera'
}